﻿// E-Book Copier
// Copyright (C) 2009 Chuan-Gen Fan
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Project: http://code.google.com/p/ebookcopier/
// Contact Author:
//    website: http://chuangen.name/
// e-mail/msn: chuangen@live.cn

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;

namespace EbookCopier
{
    /// <summary>
    /// 连续捕捉 状态枚举。
    /// </summary>
    public enum CaptureState
    {
        /// <summary>
        /// 停止状态
        /// </summary>
        Stop,
        /// <summary>
        /// 运行中
        /// </summary>
        Run,
        /// <summary>
        /// 暂停中
        /// </summary>
        Pause,
    }
    /// <summary>
    /// 封装 连续捕捉的功能。
    /// </summary>
    public class CaptureHelper
    {
        /// <summary>
        /// 延迟用的定时器。
        /// </summary>
        Timer timerDelay = null;
        /// <summary>
        /// 连续捕捉的定时器。
        /// </summary>
        Timer timerCapture = null;

        FocusRectForm cameraForm = null;
        Form owner = null;
        ICmder cmder = null;
        Properties.Settings settings = Properties.Settings.Default;
        /// <summary>
        /// 初始化类 <see cref="CaptureHelper"/> 的新实例。
        /// </summary>
        /// <param name="owner">父窗体。</param>
        public CaptureHelper(Form owner)
        {
            this.owner = owner;
            timerDelay = new Timer();
            timerDelay.Interval = 200;
            timerDelay.Tick += new EventHandler(timerDelay_Tick);

            timerCapture = new Timer();
            timerCapture.Interval = 500;
            timerCapture.Tick += new EventHandler(timerCapture_Tick);

            cameraForm = new FocusRectForm(Screen.PrimaryScreen);

            owner.Shown += new EventHandler(owner_Shown);

            this.CmderName = "模拟鼠标点击";
        }
        /// <summary>
        /// 获取或设置 剪辑区域边框的颜色。
        /// </summary>
        /// <value>The color of the focus border.</value>
        public Color FocusBorderColor
        {
            get { return cameraForm.FocusBorderColor; }
            set { cameraForm.FocusBorderColor = value; }
        }

        string cmderName = null;
        /// <summary>
        /// 获取或设置 Cmder 的名称。
        /// </summary>
        /// <value>Cmder 的名称。</value>
        public string CmderName
        {
            get { return cmderName; }
            set
            {
                if (cmderName == value)
                    return;
                cmderName = value;
                if (cmder != null)
                    cmder = null;

                Type type = CmderManager.GetCmderByName(cmderName);
                if (cmder == null)//默认是 模拟鼠标点击
                    cmder = new MouseCmder();
                else
                    cmder = Activator.CreateInstance(type) as ICmder;

                if (cmder == null)//默认是 模拟鼠标点击
                    cmder = new MouseCmder();

                cmder.PropertyChanged += new EventHandler(cmder_PropertyChanged);
                cmder.ReaderStateChanged += new EventHandler(cmder_ReaderStateChanged);

                cmder_PropertyChanged(this, EventArgs.Empty);
                cmder_ReaderStateChanged(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Apabi 状态发生变化。
        /// </summary>
        public event EventHandler ReaderStateChanged;
        void cmder_ReaderStateChanged(object sender, EventArgs e)
        {
            if (ReaderStateChanged != null)
                ReaderStateChanged(this, e);
        }


        void cmder_PropertyChanged(object sender, EventArgs e)
        {
            Type type = cmder.GetType();
            if (type == typeof(MouseCmder))
            {
                cameraForm.NextPageMouseLocation = (cmder as MouseCmder).NextPageMouseLocation;
                cameraForm.PrevPageMouseLocation = (cmder as MouseCmder).PrevPageMouseLocation;
            }
            else if (type == typeof(Apabi32Cmder))
            {
            }
            else
            { }

        }

        void owner_Shown(object sender, EventArgs e)
        {
            cameraForm.Show();
        }

        /// <summary>
        /// 当前连续捕捉要保存到的位置。
        /// </summary>
        string savedPath = "";
        /// <summary>
        /// 获取捕捉的图像保存路径。
        /// </summary>
        /// <value>保存的路径。</value>
        public string SavedPath
        {
            get { return savedPath; }
        }
        /// <summary>
        /// 文档标题缓存。
        /// </summary>
        string docTitle = "";
        /// <summary>
        /// 获取 阅览器当前打开的文档标题。
        /// </summary>
        /// <value>文档标题</value>
        public string DocumentTitle
        {
            get
            {
                docTitle = cmder.GetDocumentTitle();
                return docTitle;
            }
        }
        /// <summary>
        /// 当前正在捕捉的页码。
        /// </summary>
        public int CurrentIndex = 1;
        /// <summary>
        /// 最后一页的页码。
        /// </summary>
        public int LastPageIndex = 10;
        List<string> imagefiles = new List<string>();
        /// <summary>
        /// 获取 图像文件的路径集合。
        /// </summary>
        /// <value>The image files.</value>
        public string[] ImageFiles
        {
            get { return imagefiles.ToArray(); }
        }

        /// <summary>
        /// 当 连续捕捉状态变化时发生。
        /// </summary>
        public event EventHandler CaptureStateChanged;

        CaptureState state = CaptureState.Stop;
        /// <summary>
        /// 获取或设置 连续捕捉状态。
        /// </summary>
        /// <value>The state of the capture.</value>
        public CaptureState CaptureState
        {
            get { return state; }
            set
            {
                if (state == value)
                    return;

                state = value;
                if (CaptureStateChanged != null)
                    CaptureStateChanged(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// 获取或设置 连续捕捉的时间间隔（毫秒）。
        /// </summary>
        /// <value>时间间隔（毫秒）</value>
        public int CaptureInterval
        {
            get { return timerCapture.Interval; }
            set { timerCapture.Interval = value; }
        }
        /// <summary>
        /// 获取 阅览器程序的状态。
        /// </summary>
        /// <value>阅览器程序的状态</value>
        public ReaderState ReaderState
        {
            get { return cmder.ReaderState; }
        }
        /// <summary>
        /// 翻到上一页。
        /// </summary>
        public void PrevPage()
        { cmder.PrevPage(); }

        /// <summary>
        /// 翻到下一页。
        /// </summary>
        public void NextPage()
        { cmder.NextPage(); }

        bool isBusy = false;
        /// <summary>
        /// 设置屏幕捕捉的区域。
        /// </summary>
        public void SetSelectedRect()
        {
            if (isBusy)
                return;
            isBusy = true;

            cameraForm.SelectedRect = Rectangle.Empty;
            owner.Visible = false;

            //选择屏幕区域
            SetRectForm form = new SetRectForm(Screen.PrimaryScreen);
            if (form.ShowDialog(owner.TopLevelControl) == DialogResult.OK)
            {
                //Clipboard.SetImage(form.SelectedImage);
                cameraForm.SelectedRect = form.SelectedRect;
            }
            cameraForm.FocusStyle = FocusStyle.Normal;

            owner.Visible = true;

            isBusy = false;
        }


        /// <summary>
        /// 开始连续捕捉。
        /// </summary>
        public void Start()
        {
            if (state == CaptureState.Run)//已经在运行中
                return;
            if (cameraForm.SelectedRect == Rectangle.Empty)
            {//说明尚未确定捕捉区域
                SetSelectedRect();
            }
            else
            {
                cameraForm.PageIndex = CurrentIndex;
                imagefiles.Clear();

                docTitle = cmder.GetDocumentTitle();
                if (docTitle == null || docTitle.Trim() == "")
                    savedPath = settings.RecordPath;
                else
                    savedPath = Path.Combine(settings.RecordPath, docTitle);

                if (!Directory.Exists(savedPath))
                    Directory.CreateDirectory(savedPath);

                timerCapture.Start();
                this.CaptureState = CaptureState.Run;
            }
        }
        /// <summary>
        /// 暂停连续捕捉。
        /// </summary>
        public void Pause()
        {
            if (state == CaptureState.Pause)
                return;

            timerCapture.Enabled = false;
            this.CaptureState = CaptureState.Pause;
        }
        /// <summary>
        /// 停止连续捕捉。
        /// </summary>
        public void Stop()
        {
            if (state == CaptureState.Stop)
                return;

            timerCapture.Enabled = false;
            //设置区域为 Rectange.Empty，不显示Rect框。
            //cameraForm.SelectedRect = Rectangle.Empty;
            cameraForm.FocusStyle = FocusStyle.Normal;
            this.CaptureState = CaptureState.Stop;
        }

        void timerCapture_Tick(object sender, EventArgs e)
        {
            cameraForm.FocusStyle = FocusStyle.BeforeCopy;
            Bitmap scr = cameraForm.GetSelectedScreen();
            string path = SaveImage(scr, savedPath, "%count%");
            if (path != null && path.Trim() != "")
                imagefiles.Add(path);

            //cameraForm.FocusStyle = FocusStyle.AfterCopy;
            //timerDelay.Enabled = true;
            cameraForm.FocusStyle = FocusStyle.ContCapture;

            cmder.NextPage();

            if (CurrentIndex >= LastPageIndex)
                Stop();
            else
                CurrentIndex++;
            
            cameraForm.PageIndex = CurrentIndex;
        }

        void timerDelay_Tick(object sender, EventArgs e)
        {
            timerDelay.Enabled = false;
            //恢复状态
            if(timerCapture.Enabled)//持续拷贝中
                cameraForm.FocusStyle = FocusStyle.ContCapture;
            else
                cameraForm.FocusStyle = FocusStyle.Normal;
        }

        /// <summary>
        /// 捕捉屏幕。
        /// </summary>
        public void CaptureScreen()
        {
            if (cameraForm.SelectedRect == Rectangle.Empty)
            {//说明尚未确定捕捉区域
                SetSelectedRect();
            }
            else
            {
                //owner.Visible = false;

                cameraForm.FocusStyle = FocusStyle.BeforeCopy;
                Bitmap scr = cameraForm.GetSelectedScreen();
                SaveImage(scr, settings.RecordPath, settings.RecordFileNamedRule);
                cameraForm.FocusStyle = FocusStyle.AfterCopy;

                //owner.Visible = true;

                timerDelay.Enabled = true;
            }
        }

        /// <summary>
        /// 将图片按指定的命名规则保存到指定的目录。
        /// </summary>
        /// <param name="scr">The SCR.</param>
        /// <param name="parentPath">The parent path.</param>
        /// <param name="namedRule">The named rule.</param>
        /// <returns>返回保存成功的文件路径。失败则为 null。</returns>
        string SaveImage(Bitmap scr, string parentPath, string namedRule)
        {
            ImageFormat imgformat = null;
            string ext = ".png";
            switch (settings.ImageFormat.ToLower())
            {
                case "jpg":
                    imgformat = ImageFormat.Jpeg;
                    ext = ".jpg";
                    break;
                case "bmp":
                    imgformat = ImageFormat.Bmp;
                    ext = ".bmp";
                    break;
                case "gif":
                    imgformat = ImageFormat.Gif;
                    ext = ".gif";
                    break;
                default://PNG
                    imgformat = ImageFormat.Png;
                    ext = ".png";
                    break;
            }
            string filename = Properties.Settings.GetNewRecordFileName(namedRule, parentPath, DateTime.Now, ext);
            string filePath = System.IO.Path.Combine(parentPath, filename);
            try
            {
                scr.Save(filePath, imgformat);

                return filePath;
            }
            catch (Exception ex)
            {
                MessageBox.Show(owner.TopLevelControl, "保存失败，" + ex.Message, "错误");
                return null;
            }
        }

        /// <summary>
        /// 配置 Cmder 的选项。
        /// </summary>
        /// <param name="owner">The owner.</param>
        internal void EditOptions(IWin32Window owner)
        {
            cmder.EditOptions(owner);
        }
    }
}
